home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / xinetd / sio.1.5.6 / suite / print.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-09  |  8.0 KB  |  444 lines

  1. /*
  2.  * (c) Copyright 1992 by Panagiotis Tsirigotis
  3.  * All rights reserved.  The file named COPYRIGHT specifies the terms 
  4.  * and conditions for redistribution.
  5.  */
  6.  
  7. static char RCSid[] = "$Id: print.c,v 7.1 1992/06/01 21:39:19 panos Exp $" ;
  8.  
  9. #include <stdio.h>
  10. #include <math.h>
  11. #include <values.h>
  12. #include <string.h>
  13.  
  14. #include "sio.h"
  15.  
  16. #define FLUSH()            fflush( stdout ) ; Sflush( 1 )
  17. #define COMPARE( printf_count, sprint_count )                                        \
  18.                             if ( printf_count != sprint_count )                            \
  19.                                 printf( "printf_count = %d, sprint_count = %d\n",    \
  20.                                             printf_count, sprint_count )
  21.  
  22. enum bool { NO = 0, YES = 1 } ;
  23.  
  24. enum test_flag
  25. {
  26.     DECIMAL, HEX, CAP_HEX, OCTAL, UNSIGNED,
  27.     F_FLOAT, G_FLOAT, E_FLOAT, CAP_E_FLOAT, CAP_G_FLOAT,
  28.     CHAR, STRING,
  29.     POINTER,
  30.     BOUND,
  31.     N_FLAGS
  32. } ;
  33.  
  34. typedef enum test_flag FLAG ;
  35.  
  36. #define CHECK( f )                if ( ! flags[ f ] ) return
  37.  
  38. /*
  39.  * Flags
  40.  */
  41. enum bool flags[ N_FLAGS ] ;
  42.  
  43. char *precision ;
  44. char *width ;
  45. char *print_flags ;
  46.  
  47. int i_begin = 123456 ;
  48. int i_end = 123470 ;
  49. int i_step = 1 ;
  50.  
  51. double f_begin = 1.234567654312 ;
  52. double f_end = 2.0 ;
  53. double f_step = 0.011 ;
  54.  
  55. #define LEN( s )                    ( s ? strlen( s ) : 0 )
  56.  
  57. char *format( f )
  58.     char *f ;
  59. {
  60.     char *malloc() ;
  61.     static char *newfmt ;
  62.  
  63.     if ( newfmt )
  64.         free( newfmt ) ;
  65.  
  66.     newfmt = malloc( strlen( f )
  67.                 + LEN( precision ) + LEN( width ) + LEN( print_flags ) + 2 ) ;
  68.     (void) strcpy( newfmt, "%" ) ;
  69.     if ( print_flags )
  70.         (void) strcat( newfmt, print_flags ) ;
  71.     if ( width )
  72.         (void) strcat( newfmt, width ) ;
  73.     if ( precision )
  74.         (void) strcat( strcat( newfmt, "." ), precision ) ;
  75.     (void) strcat( newfmt, &f[1] ) ;
  76.     return( newfmt ) ;
  77. }
  78.  
  79. #define decimal_test()            integer_test( "%d %d\n", DECIMAL )
  80. #define hex_test()                integer_test( "%x %x\n", HEX )
  81. #define cap_hex_test()            integer_test( "%X %X\n", CAP_HEX )
  82. #define octal_test()                integer_test( "%o %o\n", OCTAL )
  83. #define unsigned_test()            integer_test( "%u %u\n", UNSIGNED )
  84.  
  85. void integer_test( fmt, flag )
  86.     char *fmt ;
  87.     FLAG flag ;
  88. {
  89.     int i ;
  90.     int ccs, ccp ;
  91.  
  92.     CHECK( flag ) ;
  93.     fmt = format( fmt ) ;
  94.  
  95.     for ( i = i_begin ; i < i_end ; i += i_step )
  96.     {
  97.         ccp = printf( fmt, -i, i ) ;
  98.         ccs = Sprint( 2, fmt, -i, i ) ;
  99.         FLUSH() ;
  100.         COMPARE( ccp, ccs ) ;
  101.     }
  102. }
  103.  
  104.  
  105. #define f_float_test()            fp_test( "%f\n", F_FLOAT )
  106. #define g_float_test()            fp_test( "%g\n", G_FLOAT )
  107. #define e_float_test()            fp_test( "%e\n", E_FLOAT )
  108. #define cap_e_float_test()        fp_test( "%E\n", CAP_E_FLOAT )            
  109. #define cap_g_float_test()        fp_test( "%G\n", CAP_G_FLOAT )
  110.  
  111. void fp_test( fmt, flag )
  112.     char *fmt ;
  113.     FLAG flag ;
  114. {
  115.     double d ;
  116.     double step ;
  117.     int ccs, ccp ;
  118.  
  119.     CHECK( flag ) ;
  120.     fmt = format( fmt ) ;
  121.     
  122.     for ( d = f_begin, step = f_step ; d < f_end ; d += step, step += step )
  123.     {
  124.  
  125.         ccp = printf( fmt, d ) ;
  126.         ccs = Sprint( 2, fmt, d ) ;
  127.         FLUSH() ;
  128.         COMPARE( ccp, ccs ) ;
  129.     }
  130. }
  131.  
  132.  
  133. void char_test()
  134. {
  135.     char *s = "foobar" ;
  136.     int len = strlen( s ) ;
  137.     int i ;
  138.     char *fmt = "%c\n" ;
  139.     int ccs, ccp ;
  140.  
  141.     CHECK( CHAR ) ;
  142.     fmt = format( fmt ) ;
  143.  
  144.     for ( i = 0 ; i < len ; i++ )
  145.     {
  146.         ccp = printf( fmt, s[ i ] ) ;
  147.         ccs = Sprint( 2, fmt, s[ i ] ) ;
  148.         FLUSH() ;
  149.         COMPARE( ccp, ccs ) ;
  150.     }
  151. }
  152.  
  153.  
  154. void string_test()
  155. {
  156.     static char *list[] = 
  157.     {
  158.         "foobar",
  159.         "hello",
  160.         "world",
  161.         "this is a very long string, a really long string, really, true, honest",
  162.         "i am getting tired of this",
  163.         "SO THIS IS THE END",
  164.         0
  165.     } ;
  166.     char *fmt = "%s\n" ;
  167.     char **p ;
  168.     int ccp, ccs ;
  169.  
  170.     CHECK( STRING ) ;
  171.     fmt = format( fmt ) ;
  172.  
  173.     for ( p = &list[ 0 ] ; *p ; p++ )
  174.     {
  175.         ccp = printf( fmt, *p ) ;
  176.         ccs = Sprint( 2, fmt, *p ) ;
  177.         FLUSH() ;
  178.         COMPARE( ccp, ccs ) ;
  179.     }
  180. }
  181.  
  182.  
  183. void pointer_test()
  184. {
  185.     struct foo
  186.     {
  187.         char bar1 ;
  188.         short bar2 ;
  189.         int bar3 ;
  190.         long bar4 ;
  191.         char *bar5 ;
  192.     } foo, *end = &foo, *p ;
  193.     char *fmt = "%p\n" ;
  194.     int ccp, ccs ;
  195.  
  196.     CHECK( POINTER ) ;
  197.     fmt = format( fmt ) ;
  198.  
  199.     end += 10 ;
  200.     for ( p = &foo ; p < end ; p++ )
  201.     {
  202.         ccp = printf( fmt, p ) ;
  203.         ccs = Sprint( 2, fmt, p ) ;
  204.         FLUSH() ;
  205.     }
  206. }
  207.  
  208.  
  209. /* 
  210.  * bound_test is only available on SunOS 4.x
  211.  */
  212. #if defined( sun )
  213.  
  214. void bound_test()
  215. {
  216.     char *fmt ;
  217.     double bound_values[ 10 ] ;
  218.     static char *bound_names[] =
  219.     {
  220.         "min_subnormal",
  221.         "max_subnormal",
  222.         "min_normal",
  223.         "max_normal",
  224.         "infinity",
  225.         "quiet_nan",
  226.         "signaling_nan"
  227.     } ;
  228.     int n_values ;
  229.     int i ;
  230.     int ccp, ccs ;
  231.  
  232.     bound_values[ 0 ] = min_subnormal() ;
  233.     bound_values[ 1 ] = max_subnormal() ;
  234.     bound_values[ 2 ] = min_normal() ;
  235.     bound_values[ 3 ] = max_normal() ;
  236.     bound_values[ 4 ] = infinity() ;
  237.     bound_values[ 5 ] = quiet_nan( 7L ) ;
  238.     bound_values[ 6 ] = signaling_nan( 7L ) ;
  239.     n_values = 7 ;
  240.  
  241.     CHECK( BOUND ) ;
  242.  
  243.     for ( i = 0 ; i < n_values ; i++ )
  244.     {
  245.         double d = bound_values[ i ] ;
  246.         char *name = bound_names[ i ] ;
  247.  
  248.         fmt = format( "%f (%s)\n" ) ;
  249.         ccp = printf( fmt, d, name ) ;
  250.         ccs = Sprint( 2, fmt, d, name ) ;
  251.         FLUSH() ;
  252.         COMPARE( ccp, ccs ) ;
  253.  
  254.         fmt = format( "%e (%s)\n" ) ;
  255.         ccp = printf( fmt, d, name ) ;
  256.         ccs = Sprint( 2, fmt, d, name ) ;
  257.         FLUSH() ;
  258.         COMPARE( ccp, ccs ) ;
  259.  
  260.         fmt = format( "%g (%s)\n" ) ;
  261.         ccp = printf( fmt, d, name ) ;
  262.         ccs = Sprint( 2, fmt, d, name ) ;
  263.         FLUSH() ;
  264.         COMPARE( ccp, ccs ) ;
  265.     }
  266.  
  267.     fmt = format( "%d (MININT)\n" ) ;
  268.     ccp = printf( fmt, -MAXINT-1 ) ;
  269.     ccs = Sprint( 2, fmt, -MAXINT-1 ) ;
  270.     COMPARE( ccp, ccs ) ;
  271. }
  272. #else
  273. void bound_test()
  274. {
  275. }
  276. #endif
  277.  
  278.  
  279. int get_options( argc, argv )
  280.     int argc ;
  281.     char *argv[] ;
  282. {
  283.     int arg_index = 1 ;
  284.     char *p ;
  285.     double atof() ;
  286.  
  287.     for ( arg_index = 1 ;
  288.             arg_index < argc && argv[ arg_index ][ 0 ] == '-' ; arg_index++ )
  289.     {
  290.         switch ( argv[ arg_index ][ 1 ] )
  291.         {
  292.             case 'd':
  293.                 flags[ DECIMAL ] = YES ;
  294.                 break ;
  295.             
  296.             case 'x':
  297.                 flags[ HEX ] = YES ;
  298.                 break ;
  299.             
  300.             case 'X':
  301.                 flags[ CAP_HEX ] = YES ;
  302.                 break ;
  303.             
  304.             case 'o':
  305.                 flags[ OCTAL ] = YES ;
  306.                 break ;
  307.             
  308.             case 'u':
  309.                 flags[ UNSIGNED ] = YES ;
  310.                 break ;
  311.  
  312.             case 'f':
  313.                 flags[ F_FLOAT ] = YES ;
  314.                 break ;
  315.             
  316.             case 'g':
  317.                 flags[ G_FLOAT ] = YES ;
  318.                 break ;
  319.             
  320.             case 'e':
  321.                 flags[ E_FLOAT ] = YES ;
  322.                 break ;
  323.             
  324.             case 'E':
  325.                 flags[ CAP_E_FLOAT ] = YES ;
  326.                 break ;
  327.             
  328.             case 'G':
  329.                 flags[ CAP_G_FLOAT ] = YES ;
  330.                 break ;
  331.  
  332.             case 'c':
  333.                 flags[ CHAR ] = YES ;
  334.                 break ;
  335.             
  336.             case 's':
  337.                 flags[ STRING ] = YES ;
  338.                 break ;
  339.             
  340.             case 'p':
  341.                 flags[ POINTER ] = YES ;
  342.                 break ;
  343.             
  344.             case 'b':        /* this is for checking bounds in fp formats */
  345.                 flags[ BOUND ] = YES ;
  346.                 break ;
  347.                 
  348.             case 'P':    /* precision, must be followed by a number, e.g. -P10 */
  349.                 precision = &argv[ arg_index ][ 2 ] ;
  350.                 break ;
  351.             
  352.             case 'W':    /* width, must be followed by a number, e.g. -w10 */
  353.                 width = &argv[ arg_index ][ 2 ] ;
  354.                 break ;
  355.             
  356.             case 'F':    /* flags, whatever is after the F */
  357.                 print_flags = &argv[ arg_index ][ 2 ] ;
  358.                 break ;
  359.             
  360.             /*
  361.              * Options recognized in this case:    -Vf, -Vi
  362.              * Usage: -V[if] start end step
  363.              */
  364.             case 'V':
  365.                 /*
  366.                  * Check if we have enough extra arguments
  367.                  */
  368.                 if ( argc - ( arg_index + 1 ) < 3 )
  369.                 {
  370.                     fprintf( stderr, "Insufficient # of args after V option\n" ) ;
  371.                     exit( 1 ) ;
  372.                 }
  373.                 switch ( argv[ arg_index ][ 2 ] )
  374.                 {
  375.                     case 'f':
  376.                         f_begin = atof( argv[ arg_index+1 ] ) ;
  377.                         f_end   = atof( argv[ arg_index+2 ] ) ;
  378.                         f_step  = atof( argv[ arg_index+3 ] ) ;
  379.                         break ;
  380.                     
  381.                     case 'i':
  382.                         i_begin = atoi( argv[ arg_index+1 ] ) ;
  383.                         i_end   = atoi( argv[ arg_index+2 ] ) ;
  384.                         i_step  = atoi( argv[ arg_index+3 ] ) ;
  385.                         break ;
  386.                 }
  387.                 arg_index += 3 ;
  388.                 break ;
  389.  
  390.             case 'S':
  391.                 f_step = atof( &argv[ arg_index ][ 2 ] ) ;
  392.                 break ;
  393.         }
  394.     }
  395.     return( arg_index ) ;
  396. }
  397.  
  398.  
  399. #define EQ( s1, s2 )                ( strcmp( s1, s2 ) == 0 )
  400.  
  401.  
  402. int main( argc, argv )
  403.     int argc ;
  404.     char *argv[] ;
  405. {
  406.  
  407.     if ( Sbuftype( 2, SIO_LINEBUF ) == SIO_ERR )
  408.     {
  409.         char *msg = "Sbuftype failed\n" ;
  410.  
  411.         write( 2, msg, strlen( msg ) ) ;
  412.         exit( 1 ) ;
  413.     }
  414.  
  415.     if ( argc == 1 || argc == 2 && EQ( argv[ 1 ], "ALL" ) )
  416.     {
  417.         /* perform all tests */
  418.         int i ;
  419.  
  420.         for ( i = 0 ; i < N_FLAGS ; i++ )
  421.             flags[ i ] = YES ;
  422.     }
  423.     else
  424.         (void) get_options( argc, argv ) ;
  425.  
  426.     decimal_test() ;
  427.     hex_test() ;
  428.     cap_hex_test() ;
  429.     octal_test() ;
  430.     unsigned_test() ;
  431.  
  432.     f_float_test() ;
  433.     g_float_test() ;
  434.     e_float_test() ;
  435.     cap_g_float_test() ;
  436.     cap_e_float_test() ;
  437.  
  438.     string_test() ;
  439.     char_test() ;
  440.     pointer_test() ;
  441.     bound_test() ;
  442.     exit( 0 ) ;
  443. }
  444.